programming4us
           
 
 
Programming

jQuery 1.3 : DOM Manipulation - Wrapping elements & Copying elements

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
8/18/2011 3:40:48 PM

Wrapping elements

jQuery's primary method for wrapping elements around other elements is the appropriately named .wrap(). Because we want each $(this) to be wrapped in<li></li>, we can complete our footnote code like so:

$(document).ready(function() {
$('<ol id="notes"></ol>').insertAfter('div.chapter');
$('span.footnote').each(function(index) {
$(this)
.before(
['<a href="#foot-note-',
index+1,
'" id="context-',
index+1,
'" class="context">',
'<sup>' + (index+1) + '</sup>',
'</a>'
].join('')
)
.appendTo('#notes')
.append( '&nbsp;(<a href="#context-' + (index+1) +
' ">context</a>)' )
.wrap('<li id="foot-note-' + (index+1) + ' "></li>');

});
});

Now each of the<li> elements comes complete with an id that matches the marker's href. At last, we have a set of numbered, linked footnotes:

Of course, the numbers could have been inserted before each footnote the same way they were in the paragraphs, but there is something deeply satisfying about having semantic markup dynamically generated by JavaScript.

The other jQuery methods for wrapping elements are .wrapAll() and .wrapInner(). See http://docs.jquery.com/Manipulation/wrapAll and http://docs.jquery.com/Manipulation/wrapInner for more information.

Copying elements

So far in this article we have inserted newly created elements, moved elements from one location in the document to another, and wrapped new elements around existing ones. Sometimes, though, we may want to copy elements. For example, a navigation menu that appears in the page's header could be copied and placed in the footer as well. In fact, whenever elements can be copied to enhance a page visually, it's a good opportunity to use a script. After all, why write something twice and double our chance of error when we can write it once and let jQuery do the heavy lifting?

For copying elements, jQuery's .clone() method is just what we need; it takes any set of matched elements and creates a copy of them for later use. As with the element creation process we explored earlier in this article, the copied elements will not appear in the document until we apply one of the insertion methods. For example, the following line creates a copy of the first paragraph inside <div class="chapter">:

$('div.chapter p:eq(0)').clone();

So far, the content on the page hasn't changed:

To continue the example, we can make the cloned paragraph appear before<div class="chapter">:

$('div.chapter p:eq(0)').clone().insertBefore('div.chapter');

Now the first paragraph appears twice, and because the first instance of it is no longer inside<div class="chapter">, it does not retain the styles associated with the div (most noticeably, the width):

So, using an analogy that most people should be familiar with, .clone() is to the insertion methods as copy is to paste.

Clone with events

The .clone() method by default does not copy any events that are bound to the matching element or any of its descendants. However, it can take a single Boolean parameter that, when set to true, clones events as well: .clone(true). This convenient event cloning allows us to avoid having to deal with manually rebinding events.

Cloning for pull quotes

Many websites, like their print counterparts, use pull quotes to emphasize small portions of text and attract the reader's eye. We can easily accomplish this embellishment with the .clone() method. First, let's take another look at the third paragraph of our example text:

<p>
<span class="pull-quote">It is a Law of Nature
<span class="drop">with us</span> that a male child shall
have <strong>one more side</strong> than his father</span>,
so that each generation shall rise (as a rule) one step in
the scale of development and nobility. Thus the son of a
Square is a Pentagon; the son of a Pentagon, a Hexagon; and
so on.
</p>

Notice that the paragraph begins with<span class="pull-quote">. This is the class we will be targeting for cloning. Once the copied text inside that<span> is pasted into another place, we need to modify its style properties to set it apart from the rest of the text.

A CSS diversion

To accomplish this type of styling, we'll add a pulled class to the copied<span> and give the class the following style rule in the stylesheet:

.pulled {
elementsstyle rules, applyingbackground: #e5e5e5;
position: absolute;
width: 145px;
top: -20px;
right: -180px;
padding: 12px 5px 12px 10px;
font: italic 1.4em "Times New Roman", Times, serif;
}

The pull quote now gets a light gray background, some padding, and a different font. Most important, it's absolutely positioned, 20 pixels above and 20 pixels to the right of the nearest (absolute or relative) positioned ancestor in the DOM. If no ancestor has positioning (other than static) applied, the pull quote will be positioned relative to the document<body>. Because of this, we need to make sure in the jQuery code that the cloned pull quote's parent element has position:relative set.

While the top positioning is fairly intuitive, it may not be clear at first how the pull quote box will be located 20 pixels to the left of its positioned parent. We derive the number first from the total width of the pull-quote box, which is the value of the width property plus the left and right padding, or 145 px + 5 px + 10 px, or 160 px. We then set the right property of the pull quote. A value of 0 would align the pull quote's right side with that of its parent. Therefore, to place its left side 20 px to the right of the parent, we need to move it in a negative direction 20 pixels more than its total width, or -180 px.

Back to the code

Now we can get into the jQuery. Let's start with a selector expression for all of the<span class="pull-quote"> elements, and attach an .each() method so that we can perform multiple actions as we iterate through them:

$(document).ready(function() {
$('span.pull-quote').each(function(index) {
//...
});
});

Next, we find the parent paragraph of each pull quote and apply the CSS position property:

$(document).ready(function() {
$('span.pull-quote').each(function(index) {
var $parentParagraph = $(this).parent('p');
$parentParagraph.css('position', 'relative');

});
});

Once again, we store any selector that we'll be using more than once in a variable to improve performance and readability.

We can be sure now that the CSS is all set and ready for the pull quote. At this point we can clone each<span>, add the pulled class to the copy, and insert it into the beginning of the paragraph:

$(document).ready(function() {
$('span.pull-quote').each(function(index) {
var $parentParagraph = $(this).parent('p');
$parentParagraph.css('position', 'relative');
$(this).clone()
.addClass('pulled')
.prependTo($parentParagraph);

});
});

Because we're using absolute positioning for the pull quote, the placement of it within the paragraph is irrelevant. As long as it remains inside the paragraph, it will be positioned in relation to the top and right of the paragraph, based on our CSS rules. If, however, we wanted to apply a float to the pull quote instead, its placement within the paragraph would affect its vertical position.

The paragraph, together with its pull quote, now looks like this:

This is a good start, but pull quotes typically do not retain font formatting as this one does with the bold one more side text. What we want is the text of<span class="pull-quote">, stripped of any<strong>, <em>, <a href> or other inline tags. Additionally, it would be nice to be able to modify the pull quote a bit, dropping some words and replacing them with ellipses. For this, we have wrapped a few words of text in the example in a<span> tag:<span class="drop">with us</span>.

We'll apply the ellipsis first, and then replace all of the pull-quote HTML with a stripped, text-only version:

$(document).ready(function() {
$('span.pull-quote').each(function(index) {
var $parentParagraph = $(this).parent('p');
$parentParagraph.css('position', 'relative');
var $clonedCopy = $(this).clone();

$clonedCopy
.addClass('pulled')
.find('span.drop')
.html('&hellip;')
.end()
.prependTo($parentParagraph);
var clonedText = $clonedCopy.text();
$clonedCopy.html(clonedText);

});
});
So, we start the cloning process this time by storing the clone in a variable. The variable is necessary this time because we can't work on it completely within the same chain. Notice, too, that after we find <span class="drop"> and replace its HTML with an ellipsis (&hellip;), we use .end() to back out of the last query, .find('span.drop'). This way, we're inserting the whole copy, not just the ellipsis, at the beginning of the paragraph.

At the end, we set one more variable, clonedText, to the text-only contents of the copy; then we use these text-only contents as a replacement for the HTML of the copy. Now, the pull quote looks like this:

Evidently, another<span class="pull-quote"> has been added to a later paragraph to ensure that the code works for multiple elements.

Prettifying the pull quotes

The pull quotes are now working as expected, with child elements stripped and ellipses added where text should be dropped.

Since one of the goals is to add visual appeal, though, we would do well to give the pull quotes rounded corners with drop shadows. However, the variable height of the pull-quote boxes is problematic because we'll need to apply two background images to a single element, which is impossible for every browser at the moment except the most recent builds of Safari.

To overcome this limitation, we can wrap another<div> around the pull quotes:

$(document).ready(function() {
$('span.pull-quote').each(function(index) {
var $parentParagraph = $(this).parent('p');
$parentParagraph.css('position', 'relative');
var $clonedCopy = $(this).clone();
$clonedCopy
.addClass('pulled')
.find('span.drop')
.html('&hellip;')
.end()
.prependTo($parentParagraph)
.wrap('<div class="pulled-wrapper"></div>');

var clonedText = $clonedCopy.text();
$clonedCopy.html(clonedText);
});
});

We also need to modify the CSS, of course, to account for the new<div> and the two background images:

.pulled-wrapper {
background: url(pq-top.jpg) no-repeat left top;
position: absolute;
width: 160px;
right: -180px;
padding-top: 18px;
}
.pulled {
background: url(pq-bottom.jpg) no-repeat left bottom;
position: relative;
display: block;
width: 140px;
padding: 0 10px 24px 10px;
font: italic 1.4em "Times New Roman", Times, serif;
}

Here, some of the rules formerly applied to<span class="pulled"> are applied to<div class="pulled-wrapper"> instead. A couple of width and padding adjustments take into account the design of the background image borders, and the .pulled rule has its position and display properties modified in order to appear correctly for all browsers.

Here is one final look at the newly primped pull quotes in their native habitat:


DOM manipulation methods in a nutshell

The extensive DOM manipulation methods that jQuery provides vary according to their task and their location. The following outline can serve as a reminder of which methods we can use to accomplish any of these tasks, just about anywhere.

  1. 1. To create new elements from HTML, user the $() factory function.

  2. 2. To insert new element(s) inside every matched element, use:

    • .append()

    • .appendTo()

    • .prepend()

    • .prependTo()

  3. 3. To insert new element(s) adjacent to every matched element, use:

    • .after()

    • .insertAfter()

    • .before()

    • .insertBefore()

  4. 4. To insert new element(s) around every matched element, use:

    • .wrap()

    • .wrapAll()

    • .wrapInner()

  5. 5. To replace every matched element with new element(s) or text, use:

    • .html()

    • .text()

    • .replaceAll()

    • .replaceWith()

  6. 6. To remove element(s) inside every matched element, use:

    • .empty()

  7. 7. To remove every matched element and descendants from the document without actually deleting them, use:

    • .remove()

Other -----------------
- iOS SDK : Debugging (part 4) - Instruments—Leaks
- iOS SDK : Debugging (part 3) - NSZombieEnabled
- iOS SDK : Debugging (part 2) - Watchpoints
- iOS SDK : Debugging (part1 )
- iOS SDK : Installing Applications on an iPhone
- Software Testing with Visual Studio Team System 2008 : Web Testing - Recording a test
- Software Testing with Visual Studio Team System 2008 : Unit testing web services & Code coverage unit test
- .NET Debugging : Introduction to the Tools - SOS & SOSEX
- .NET Debugging : CLR 4.0 - Synchronization & Interoperability
- iPhone Programming : Connecting to the Network - Getting Data from the Internet
- iPhone Programming : Connecting to the Network - Sending Email
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Check Results
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Read and Write Files
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Get Dates and Times
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Work with Text
- A Technical Overview of the Mobile Web : THE TECHNICAL CHALLENGES OF MOBILE DEVICES (part 2)
- A Technical Overview of the Mobile Web : THE TECHNICAL CHALLENGES OF MOBILE DEVICES (part 1) - Physical Constraints
- Parallel Programming with Microsoft Visual Studio 2010 : Task Parallelism - Unhandled Exceptions in Tasks
- Parallel Programming with Microsoft Visual Studio 2010 : Introduction to Parallel Tasks
- jQuery 1.3 : DOM Manipulation - Moving elements
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us